package com.easymin.weixin.common;

import com.google.common.collect.Lists;

import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class SignHelper {

  /**
   * 构建签名.
   */
  
  public static String sign(String message, String secret) {

    return HmacUtils.hmacSha256Hex(secret, message);
  }

  /**
   * 从 HttpServletRequest 中构建签名消息.
   */
  
  public static String buildSignMessage(HttpServletRequest request) {

    List<String> params = new LinkedList<String>();

    Enumeration<String> parameterNames = request.getParameterNames();
    while (parameterNames.hasMoreElements()) {

      String paramName = parameterNames.nextElement();
      params.add(paramName);
    }

    Collections.sort(params); //排序

    SignMessageBuilder builder = new SignMessageBuilder();

    for (String pa : params) {

      String value = request.getParameter(pa);
      if (StringUtils.isNotBlank(value) && !pa.equalsIgnoreCase("sign") 
          && !pa.equalsIgnoreCase("appId")) {
        builder.add(pa, value);
      }
    }

    return builder.build();
  }

  /**
   * 从 Map 中构建签名消息.
   */
  
  public static String buildSignMessage(Map<String, String> map) {

    List<String> params = new LinkedList<String>();

    params.addAll(map.keySet());

    Collections.sort(params); //排序

    SignMessageBuilder builder = new SignMessageBuilder();

    for (String pa : params) {

      String value = map.get(pa);

      if (StringUtils.isNotBlank(value) && !pa.equalsIgnoreCase("sign") 
          && !pa.equalsIgnoreCase("appId")) {
        builder.add(pa, value);
      }
    }

    return builder.build();
  }

  /**
   * 签名消息 builder.
   */
  public static class SignMessageBuilder {

    private List<String> kv;

    public SignMessageBuilder() {

      this.kv = Lists.newLinkedList();
    }

    /**
     * 添加Key Value.
     */
    public SignMessageBuilder add(String key, String value) {
      StringBuilder builder = new StringBuilder();
      builder.append(key);
      builder.append("=");
      builder.append(value);

      this.kv.add(builder.toString());

      return this;
    }
    
    /**
     * 构建字符串.
     */
    public String build() {

      int size = kv.size();

      StringBuilder builder = new StringBuilder();

      for (int i = 0; i < size; i++) {
        builder.append(kv.get(i));
        if (i == size - 1) {
          continue;
        } else {
          builder.append("&");
        }
      }

      return builder.toString();
    }

  }
}
